
/* GCSx
** SPAWNPROP.CPP
**
** Spawn-point properties dialog
*/

/*****************************************************************************
** Copyright (C) 2003-2006 Janson
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
*****************************************************************************/

#include "all.h"

// Properties dialog

SpawnPropertiesDialog* SpawnPropertiesDialog::dialogWithSprite = NULL;
SpawnPropertiesDialog* SpawnPropertiesDialog::dialogNoSprite = NULL;
// @TODO: save as global setting
int SpawnPropertiesDialog::autoSync = 1;

SpawnPropertiesDialog* SpawnPropertiesDialog::createWithSprite() { start_func
    if (!dialogWithSprite) {
        dialogWithSprite = new SpawnPropertiesDialog(1);
    }
    return dialogWithSprite;
}
SpawnPropertiesDialog* SpawnPropertiesDialog::createNoSprite() { start_func
    if (!dialogNoSprite) {
        dialogNoSprite = new SpawnPropertiesDialog(0);
    }
    return dialogNoSprite;
}

void SpawnPropertiesDialog::destroy() { start_func
    if (dialogWithSprite) {
        delete dialogWithSprite;
        dialogWithSprite = NULL;
    }
    if (dialogNoSprite) {
        delete dialogNoSprite;
        dialogNoSprite = NULL;
    }
}

SpawnPropertiesDialog::SpawnPropertiesDialog(int isSprite) : ImageDialog() { start_func
    initialized = 0;
    tree = NULL;
    hasSprite = isSprite;
}

SpawnPropertiesDialog::~SpawnPropertiesDialog() { start_func
    if (tree) {
        WidgetScroll* ws = dynamic_cast<WidgetScroll*>(tree->getParent());
        if (ws) ws->newClient();
        delete tree;
    }
}

Dialog::ButtonAction SpawnPropertiesDialog::verifyEntry(int buttonId, Dialog::ButtonAction buttonType) { start_func
    if ((buttonType != BUTTON_APPLY) && (buttonType != BUTTON_OK)) return BUTTON_DEFAULT;

    // No script?
    TreeView* item = tree->findSelected();
    if ((!item) || (!wWorld->findScript(item->getCode()))) {
        if (hasSprite) {
            // No sprite?
            AnimGroup* animGroup = NULL;
            TileSet* tileSet = NULL;
            runComplete(&animGroup, &tileSet, NULL, 1);
            if ((!animGroup) && (!tileSet)) {
                guiErrorBox("You must select at least a script or an image for a sprite.", errorTitleInvalidEntry);
                return BUTTON_NOTHING;
            }
        }
        else {
            // A sprite-less spawn- must have a script
            guiErrorBox("You must select a script.", errorTitleInvalidEntry);
            return BUTTON_NOTHING;
        }
    }

    return Dialog::verifyEntry(buttonId, buttonType);
}

int SpawnPropertiesDialog::run(string* title, Script** script, AnimGroup** animGroup, TileSet** tileSet, int* animTileId, WorldEdit* whichWorld) { start_func
    assert(title);
    assert(script);
    assert(animGroup);
    assert(tileSet);
    assert(animTileId);
    assert(whichWorld);
    
    titleS = title;
    wWorld = whichWorld;
    
    // @TODO: Tooltips on this dialog
    if (!initialized) {
        Widget* w = NULL;
        
        w = new WCheckBox(ID_SYNC,"\tCopy settings from script", &autoSync, 1);
        w->addTo(this);
        
        w = new WStatic(ID_SCRIPTLABEL, "\tScript:");
        w->addTo(this);
        
        tree = new TreeView(blankString, NULL, 0, NULL, 1);
        tree->addTo(this, -1, 5);

        w = new WStatic(ID_LABEL, "\tName:");
        w->addTo(this);

        w = new WTextBox(ID_NAME, title, 0);
        w->addTo(this);

        if (hasSprite) {
            w = new WStatic(ID_LABEL, "\tLibrary:");
            w->addTo(this);
            
            addLibTree(ID_LIBRARY);

            makePretty(2, 0);
            
            w = findWidget(ID_LIBRARY);
            int x = w->getX() + w->getWidth() + GUI_DIALOG_GUTTERWIDTH;
            int h = w->getY() + w->getHeight();
            int y = findWidget(ID_SYNC)->getY();
            int y2 = findWidget(ID_SCRIPTLABEL)->getY();

            w = new WStatic(ID_LABEL, "\tImage:");
            w->addTo(this);
            w->move(x, y);
            ++lastWidgetArranged;

            addImgChoose(ID_IMAGE);
            w = findWidget(ID_IMAGE);
            w->move(x, y2);
            w->resize(w->getWidth(), h - y2);
            
            resize(width + w->getWidth() + GUI_DIALOG_GUTTERWIDTH, height);
            ++lastWidgetArranged;
        }
        
        w = new WButton(ID_OK, messageBoxOK, BUTTON_OK);
        w->addTo(this);

        w = new WButton(ID_CANCEL, messageBoxCancel, BUTTON_CANCEL);
        w->addTo(this);

        makePretty(2, 0);
        setTitle("Object Properties");
        initialized = 1;
    }
    else {
        findWidget(ID_NAME)->changeStorage(title);
        findWidget(ID_SYNC)->changeStorage(&autoSync);
    }

    TreeView* item;
    tree->removeAll();
    if (hasSprite) tree->insert(new TreeView("(none)", this, 0, treeViewWrap), *script == NULL);

    World::ScriptIndex::const_iterator end = wWorld->endScript();
    for (World::ScriptIndex::const_iterator pos = wWorld->beginScript(); pos != end; ++pos) {
        ScriptEdit* toAdd = dynamic_cast<ScriptEdit*>((*pos).second);
        if (toAdd->getType() == Script::SCRIPT_CODE) {
            tree->insert(item = new TreeView(toAdd->getName(), this, toAdd->getId(), treeViewWrap), *script == toAdd);
            item->setIcon(toAdd->getDefaultId() ? 13 : 12);
        }
    }
    
    if (hasSprite) {
        runPrep(wWorld, *animGroup, *tileSet, *animTileId);
    }

    // Hit OK?
    if (runModal() == ID_OK) {
        // Script
        item = tree->findSelected();
        if (item) *script = wWorld->findScript(item->getCode());
        else *script = NULL;
        
        // Sprite
        if (hasSprite) {
            runComplete(animGroup, tileSet, animTileId);
        }
        return 1;
    }
    
    if (hasSprite) runComplete();
    return 0;
}

int SpawnPropertiesDialog::treeViewWrap(void* ptr, int code, int command, int check) { start_func
    return ((SpawnPropertiesDialog*)ptr)->treeView(code, command, check);
}

int SpawnPropertiesDialog::treeView(int code, int command, int check) { start_func
    if (check) {
        return Window::COMMAND_HIDE;
    }

    if ((command == LV_MOVE) && (open)) {
        findWidget(ID_SYNC)->apply();
        if (autoSync) {
            if (code) {
                Script* script = wWorld->findScript(code);
                if (script) {
                    *titleS = script->getName();
                    findWidget(ID_NAME)->load();
                    
                    selectImage(script->getDefaultAnimgroup(), script->getDefaultTileset(),
                                script->getDefaultId());
                }
            }
            else {
                *titleS = blankString;
                findWidget(ID_NAME)->load();
            }
        }
        return 1;
    }

    return 0;
}
